#include "EpilFunctionArgumentsParser.h"
#include "EpilParserException.h"
#include "EpilExpressionListParser.h"
#include "EpilStringExpressionCode.h"
#include "EpilTableConstructorParser.h"
#include "EpilPointerHelper.h"


EpilFunctionArgumentsParser::EpilFunctionArgumentsParser( EpilTokenStream & tokens )
: EpilSyntaxParserBase( tokens )
{
}


void EpilFunctionArgumentsParser::Parse()
{
	switch( this->GetTokens().GetCurrentToken().type )
	{
	case ETT_OpenParenthese:
		{
			// funcargs -> `(' [ explist1 ] `)'
			this->GetTokens().MoveToNext();

			if( this->GetTokens().GetCurrentToken().type == ETT_CloseParenthese )
			{
				// void function.
				this->GetTokens().MoveToNext();
				return;
			}

			EpilExpressionListParser exprListParser( this->GetTokens() );
			exprListParser.Parse();
			m_arguments = exprListParser.GetExpressions();

			if( this->GetTokens().GetCurrentToken().type != ETT_CloseParenthese )
			{
				EpilPointerHelper::DeleteItemsAndClear( m_arguments );
				throw EpilParserException( t("\')\' expected."), this->GetTokens().GetCurrentToken().location );
			}
			this->GetTokens().MoveToNext();
		}
		break;
	case ETT_OpenBrace:
		{
			// funcargs -> constructor
			EpilTableConstructorParser constructorParser( this->GetTokens() );
			constructorParser.Parse();
			m_arguments.push_back( constructorParser.GetConstructor() );
		}
		break;
	case ETT_String:
		{
			// funcargs -> STRING
			EpilStringExpressionCode * str = new EpilStringExpressionCode( this->GetTokens().GetCurrentToken().location );
			str->SetString( this->GetTokens().GetCurrentToken().text );
			m_arguments.push_back( str );
			this->GetTokens().MoveToNext();
		}
		break;
	}
}